/*
 * Copyright (c) 2024 HiSilicon Technologies CO., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "pinctrl.h"
#include "adc.h"
#include "adc_porting.h"
#include "i2c.h"
#include "gpio.h"
#include "hal_gpio.h"
#include "osal_debug.h"
#include "ssd1306_fonts.h"
#include "ssd1306.h"
#include "soc_osal.h"
#include "aht20.h"
#include "app_init.h"
#include "aht20_test.h"

#define CONFIG_I2C_SCL_MASTER_PIN 15
#define CONFIG_I2C_SDA_MASTER_PIN 16
#define CONFIG_I2C_MASTER_PIN_MODE 2
#define I2C_MASTER_ADDR 0x0
#define I2C_SLAVE1_ADDR 0x38
#define I2C_SET_BANDRATE 400000
#define I2C_TASK_STACK_SIZE 0x1000
#define I2C_TASK_PRIO 17

#define Pepole GPIO_02
#define Fire GPIO_14

const unsigned char headSize[] = {64, 64};
float temp = 0.0f;
float humi = 0.0f;
uint32_t ad_val=0;
uint32_t ad_val1=0;
uint8_t people_v=0;

void app_i2c_init_pin(void)
{
    uapi_pin_set_mode(CONFIG_I2C_SCL_MASTER_PIN, CONFIG_I2C_MASTER_PIN_MODE);
    uapi_pin_set_mode(CONFIG_I2C_SDA_MASTER_PIN, CONFIG_I2C_MASTER_PIN_MODE);
}

/**
 * 汉字字模在线： https://www.23bei.com/tool-223.html
 * 数据排列：从左到右从上到下
 * 取模方式：横向8位左高位
 * 字体总类：[HZK1616宋体]
 **/
void TempHumChinese(void)
{
    const uint32_t W = 16;
    uint8_t fonts[][32] = {
        {/*-- ID:0,字符:"温",ASCII编码:CEC2,对应字:宽x高=12x12,画布:宽W=16 高H=12,共24字节*/
            0x4F,0xC0,0x28,0x40,0x0F,0xC0,0x88,0x40,0x4F,0xC0,0x28,0x40,0x40,0x00,0xDF,0xE0,
            0x54,0xA0,0x54,0xA0,0x54,0xA0,0x7F,0xF0},
        {/*-- ID:1,字符:"度",ASCII编码:B6C8,对应字:宽x高=12x12,画布:宽W=16 高H=12,共24字节*/
            0x02,0x00,0x3F,0xE0,0x24,0x80,0x3F,0xE0,0x24,0x80,0x27,0x80,0x20,0x00,0x2F,0x80,
            0x25,0x00,0x42,0x00,0x8D,0x80,0xB0,0x70}};
    uint8_t fonts2[][32] = {
        {/*-- ID:0,字符:"湿",ASCII编码:CAAA,对应字:宽x高=12x12,画布:宽W=16 高H=12,共24字节*/
            0x4F,0xE0,0x28,0x20,0x0F,0xE0,0x88,0x20,0x4F,0xE0,0x28,0x20,0x42,0x90,0xD2,0xA0,
            0x4A,0xC0,0x4A,0x80,0x42,0x80,0x7F,0xF0},
        {/*-- ID:1,字符:"度",ASCII编码:B6C8,对应字:宽x高=12x12,画布:宽W=16 高H=12,共24字节*/
            0x02,0x00,0x3F,0xE0,0x24,0x80,0x3F,0xE0,0x24,0x80,0x27,0x80,0x20,0x00,0x2F,0x80,
            0x25,0x00,0x42,0x00,0x8D,0x80,0xB0,0x70}};
    uint8_t fonts3[][32] = {
        {/*-- ID:0,字符:"气",ASCII编码:C6F8,对应字:宽x高=12x12,画布:宽W=16 高H=12,共24字节*/
            0x10,0x00,0x10,0x40,0x3F,0xE0,0x40,0x00,0x9F,0x80,0x00,0x00,0x7F,0x80,0x00,0x80,
            0x00,0x80,0x00,0x90,0x00,0x50,0x00,0x30},
        {/*-- ID:1,字符:"体",ASCII编码:CCE5,对应字:宽x高=12x12,画布:宽W=16 高H=12,共24字节*/
            0x21,0x00,0x21,0x20,0x3F,0xF0,0x41,0x00,0x43,0x80,0xC5,0x40,0x45,0x40,0x49,0x20,
            0x57,0xD0,0x41,0x00,0x41,0x00,0x41,0x00}};
    for (size_t i = 0; i < sizeof(fonts) / sizeof(fonts[0]); i++) {
        ssd1306_DrawRegion(i * W, 3, W, fonts[i], sizeof(fonts[0])); // x轴坐标i*w，y轴坐标3，宽度为16
    }
    for (size_t j = 0; j < sizeof(fonts2) / sizeof(fonts2[0]); j++) {
        ssd1306_DrawRegion(j * W, 25, W, fonts2[j], sizeof(fonts2[0])); // x轴坐标i*w，y轴坐标35，宽度为16
    }
    for (size_t j = 0; j < sizeof(fonts3) / sizeof(fonts3[0]); j++) {
        ssd1306_DrawRegion(j * W, 47, W, fonts3[j], sizeof(fonts3[0])); // x轴坐标i*w，y轴坐标47，宽度为16
    }
}

void test_adc_callback(uint8_t ch, uint32_t *buffer, uint32_t length, bool *next) 
{ 
    UNUSED(next);
    uint32_t val=0;
    for (uint32_t i = 0; i < length; i++) {
        val+=buffer[i];
        if(i==length-1 && ch == 4)
        {
            ad_val = val/length;
            val=0;
            printf("channel: %d, voltage: %umv\r\n", ch, ad_val);
        }
    } 
}

void app_adc_init(void)
{
    uapi_adc_init(ADC_CLOCK_500KHZ);
    uapi_adc_power_en(AFE_SCAN_MODE_MAX_NUM, true);
    adc_scan_config_t config = {
        .type = 0,
        .freq = 1,
    };
    uapi_adc_auto_scan_ch_enable(ADC_CHANNEL_4, config, test_adc_callback);
    uapi_adc_auto_scan_ch_disable(ADC_CHANNEL_4);
    osal_mdelay(1000);
}

void Aht20TestTask(void)
{
    uint32_t retval = 0;
    adc_scan_config_t config = {
        .type = 0,
        .freq = 1,
    };
    static char templine[32] = {0};
    static char humiline[32] = {0};
    static char adline[32] = {0};
    uint32_t baudrate = I2C_SET_BANDRATE;
    uint32_t hscode = I2C_MASTER_ADDR;
    uapi_pin_init();
    app_i2c_init_pin();
    app_adc_init();
    uapi_pin_set_mode(Fire,PIN_MODE_0);
    uapi_pin_set_pull(Fire,PIN_PULL_TYPE_DISABLE);
    uapi_gpio_set_dir(Fire,GPIO_DIRECTION_INPUT);
    uapi_pin_set_mode(Pepole,PIN_MODE_0);
    uapi_pin_set_pull(Pepole,PIN_PULL_TYPE_DISABLE);
    uapi_gpio_set_dir(Pepole,GPIO_DIRECTION_INPUT);
    errcode_t ret = uapi_i2c_master_init(1, baudrate, hscode);
    if (ret != 0) {
        printf("i2c init failed, ret = %0x\r\n", ret);
    }
    ssd1306_Init();
    ssd1306_Fill(Black);
    ssd1306_SetCursor(0, 0);
    while (AHT20_Calibrate() != 0) {
        printf("AHT20 sensor init failed!\r\n");
        osal_mdelay(100); // 10ms在判断设备是否复位成功
    }
    
    while (1) {
        people_v=1-uapi_gpio_get_val(Pepole);
        ad_val1=1-uapi_gpio_get_val(Fire);
        uapi_adc_auto_scan_ch_enable(ADC_CHANNEL_4, config, test_adc_callback);
        uapi_adc_auto_scan_ch_disable(ADC_CHANNEL_4);
        TempHumChinese();
        retval = AHT20_StartMeasure();
        //printf("AHT20_StartMeasure: %d\r\n", retval);
        retval = AHT20_GetMeasureResult(&temp, &humi);
        if (retval != 0) {
            printf("get humidity data failed!\r\n");
        }
        ssd1306_SetCursor(32, 4); /* x坐标为32，y轴坐标为8 */
        int ret = sprintf(templine, ": %.2f", temp);
        if (ret < 0) {
            printf("temp failed\r\n");
        }
        ssd1306_DrawString(templine, Font_7x10, White);

        ret = sprintf(humiline, ": %.2f", humi);
        if (ret < 0) {
            printf("humi failed\r\n");
        }
        ssd1306_SetCursor(32, 26); /* x坐标为32，y轴坐标为40 */
        ssd1306_DrawString(humiline, Font_7x10, White);

        ret = sprintf(adline, ": %u  ", ad_val);
        if(ret < 0){
             printf("ad failed\r\n");
        }
        ssd1306_SetCursor(32,48);
        ssd1306_DrawString(adline, Font_7x10, White);
        printf("temp = %s, humi = %s, ad = %s, fire = %u, peop = %d \r\n", templine, humiline, adline, ad_val1, people_v);

        ssd1306_UpdateScreen();
        osal_mdelay(2000);
    }
}


